<template>
    <div class="content-container">
        <el-card>
            <!-- 查询部分 -->
            <el-form :model="query" :inline="true" class="demo-form-inline">
                <el-form-item label="客户端">
                    <el-input v-model="query.clientId" clearable />
                </el-form-item>

                <el-form-item>
                    <el-button type="success" @click="formQuery(false)">查询</el-button>
                    <el-button type="warning" @click="formQuery(true)">重置</el-button>
                    <el-button type="primary" @click="openDialog(null)">新增</el-button>

                    <el-popconfirm confirm-button-text="确认" cancel-button-text="取消" title="确认删除选中数据?"
                        @confirm="removeRows" width="200px">
                        <template #reference>
                            <el-button type="danger">删除</el-button>
                        </template>
                    </el-popconfirm>
                </el-form-item>
            </el-form>
            <!-- 数据部分 -->
            <el-table max-height="600px" show-overflow-tooltip :data="tableData" stripe
                style="width: 100%; margin-top: 10px" ref="tableDataRef">
                <el-table-column type="selection" />
                <el-table-column prop="clientId" label="客户端" />

                <el-table-column prop="clientAuthenticationMethod" label="认证方式" />
                <el-table-column prop="authorizationGrantType" label="授权方式" />
                <el-table-column prop="tokenValidTime" label="授权码时长" />
                <el-table-column prop="refreshTokenValidTime" label="刷新凭证时长" />
                <el-table-column prop="redirectUris" label="回调地址" />

                <el-table-column prop="clientIdIssuedAt" label="创建时间" />
                <el-table-column fixed="right" label="操作" width="120">
                    <template #default="scope">
                        <el-button @click="openDialog(scope.row)" link type="primary">
                            编辑
                        </el-button>
                        <el-button @click="viewDialog(scope.row)" link type="primary">
                            查看
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 分页 -->
            <div style="margin-top: 20px">
                <el-pagination v-model:current-page="query.current" v-model:page-size="query.size"
                    :page-sizes="[100, 200, 300, 400]" small background layout="total, sizes, prev, pager, next, jumper"
                    :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
            </div>

            <el-dialog v-model="dialogVisible" :title="(formData.id ? '编辑' : '新增') + '客户端信息'" :show-close="false"
                :close-on-click-modal="false">

                <el-form :rules="rules" :model="formData" ref="formDataRef" label-width="130px">

                    <el-form-item prop="clientId" label="客户端标识">
                        <el-input v-model="formData.clientId" clearable placeholder="请输入客户端标识" />
                    </el-form-item>
                    <el-form-item prop="clientSecret" label="客户端密钥">
                        <el-input v-model="formData.clientSecret" clearable placeholder="请输入客户端密钥" />
                    </el-form-item>

                    <el-form-item prop="clientAuthenticationMethods" label="客户端认证">
                        <el-select v-model="formData.clientAuthenticationMethods" placeholder="请选择认证方式" multiple>
                            <el-option label="Basic认证" value="client_secret_basic" />
                            <el-option label="表单认证" value="client_secret_post" />
                            <el-option label="JWT认证" value="client_secret_jwt" />
                            <el-option label="非对称加密JWT认证" value="private_key_jwt" />
                        </el-select>
                    </el-form-item>
                    <el-form-item prop="authorizationGrantTypes" label="授权方式">
                        <el-select v-model="formData.authorizationGrantTypes" placeholder="请选择授权方式" multiple>
                            <el-option label="授权码" value="authorization_code" />
                            <el-option label="刷新令牌" value="refresh_token" />
                            <el-option label="密码" value="password" />
                            <el-option label="客户端凭证" value="client_credentials" />
                        </el-select>
                    </el-form-item>
                    <el-form-item prop="redirectUri" label="客户端回调">
                        <el-input v-model="formData.redirectUri" clearable placeholder="请输入回调地址" />
                    </el-form-item>

                    <el-form-item prop="scopes" label="客户端范围">
                        <el-input v-model="formData.scopes" clearable placeholder="请输入授权范围" />
                    </el-form-item>
                    <el-form-item prop="requireAuthorizationConsent" label="授权需确认">
                        <el-select v-model="formData.requireAuthorizationConsent" placeholder="请选择">
                            <el-option label="需要" :value="true" />
                            <el-option label="不需要" :value="false" />
                        </el-select>
                    </el-form-item>

                    <el-form-item prop="tokenValidTime" label="凭证有效期">
                        <el-input v-model.number="formData.tokenValidTime" clearable placeholder="请输入accessToken有效期(分)">
                            <template #append>分钟</template>
                        </el-input>
                    </el-form-item>
                    <el-form-item prop="refreshTokenValidTime" label="刷新凭证有效期">
                        <el-input v-model.number="formData.refreshTokenValidTime" clearable
                            placeholder="请输入refreshToken有效期">
                            <template #append>分钟</template>
                        </el-input>
                    </el-form-item>

                </el-form>

                <template #footer>
                    <span class="dialog-footer">
                        <el-button @click="dialogVisible = false">取消</el-button>
                        <el-button type="primary" @click="formSubmit">确认</el-button>
                    </span>
                </template>
            </el-dialog>

            <el-dialog v-model="viewVisible" width="60%" :show-close="false" :close-on-click-modal="false">
                <el-form>

                    <el-form-item>
                        <el-input v-model="viewData.clientId" disabled>
                            <template #prepend>客户端标识</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.clientSecret" disabled>
                            <template #prepend>客户端密钥</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.clientAuthenticationMethod" disabled>
                            <template #prepend>客户端认证</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.authorizationGrantType" disabled>
                            <template #prepend>客户端授权</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.redirectUri" disabled>
                            <template #prepend>客户端回调</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.scopes" disabled>
                            <template #prepend>客户端授权</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.requireAuthorizationConsent" disabled>
                            <template #prepend>授权需确认</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.tokenValidTime" disabled>
                            <template #prepend>凭证有效期</template>
                            <template #append>分钟</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.refreshTokenValidTime" disabled>
                            <template #prepend>刷新凭证有效期</template>
                            <template #append>分钟</template>
                        </el-input>
                    </el-form-item>

                    <el-form-item>
                        <el-input v-model="viewData.clientIdIssuedAt" disabled>
                            <template #prepend>创建时间</template>
                        </el-input>
                    </el-form-item>
                </el-form>
                <template #footer>
                    <span class="dialog-footer">
                        <el-button @click="viewVisible = false">关闭</el-button>
                    </span>
                </template>
            </el-dialog>
        </el-card>
    </div>
</template>
<script setup lang="ts" name="Client">
import { onMounted, ref, reactive, toRefs } from 'vue'
import type {
    Oauth2RegisteredClient,
    ClientModDTO,
    ClientQueryDTO,
    ClientVo,
} from '@/api/acl/client/type'
import {
    clientAdd,
    clientDel,
    clientMod,
    clientQuery,
} from '@/api/acl/client'
import { ElNotification } from 'element-plus'

const formDataRef = ref()
const tableDataRef = ref()
const initQuery = () => {
    return { current: 1, size: 10 } as ClientQueryDTO
}
const state = reactive<any>({
    query: initQuery(),
    tableData: [] as Oauth2RegisteredClient[],
    total: 0,
    dialogVisible: false,
    viewVisible: false,
    viewData: {} as ClientVo,
    formData: { requireAuthorizationConsent: false } as ClientModDTO,
    rules: {
        clientId: [{ required: true, message: '客户端id不能为空', trigger: 'blur' }],
        clientSecret: [{ required: true, message: '客户端密钥不能为空', trigger: 'blur' }],
        clientAuthenticationMethods: [{ required: true, message: '认证方式不能为空', trigger: 'blur' }],
        scopes: [{ required: true, message: '授权范围不能为空', trigger: 'blur' }],
        authorizationGrantTypes: [{ required: true, message: '授权方式不能为空', trigger: 'blur' }],
        tokenValidTime: [{ required: true, message: 'accessToken有效期不能为空', trigger: 'blur' }],
        refreshTokenValidTime: [{ required: true, message: 'refreshToken有效期不能为空', trigger: 'blur' }],
    },
})
const {
    query,
    tableData,
    total,
    dialogVisible,
    formData,
    rules,
    viewVisible,
    viewData,
} = toRefs(state)
const openDialog = (data: any) => {
    if (formDataRef.value) {
        formDataRef.value.resetFields()
    }

    formData.value = data == null ? {} : data
    dialogVisible.value = true
}
const viewDialog = (data: any) => {
    viewVisible.value = true
    viewData.value = data
}
const handleSizeChange = (size: number) => {
    query.value.size = size
    buildTable()
}
const handleCurrentChange = (current: number) => {
    query.value.current = current
    buildTable()
}
onMounted(() => {
    buildTable()
})
const buildTable = async () => {
    const result = await clientQuery(query.value)
    tableData.value = result.data.rows
    total.value = result.data.total
}

const formQuery = (reset: boolean) => {
    reset ? (query.value = initQuery()) : query.value
    buildTable()
}
const formSubmit = async () => {
    await formDataRef.value?.validate()
    if (formData.value.id) {
        await clientMod(formData.value)
    } else {
        await clientAdd(formData.value)
    }
    dialogVisible.value = false
    await buildTable()
}
const removeRows = async () => {
    const rows = tableDataRef.value.getSelectionRows()
    if (rows.length == 0) {
        ElNotification({
            title: '删除失败',
            message: '请选择要删除的数据',
            type: 'warning',
        })
        return
    }
    const ids = rows.map((each: any) => each.id)
    await clientDel({ ids: ids })
    await buildTable()
}
</script>
<style scoped lang="scss">
.content-container {
    padding: 12px;
}
</style>